﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SPMS.Log.Core;
using SPMS.Log.Repository;
using SPMS.Utility;

namespace SPMS.Log.Appender
{
    /// <summary>
    /// 日志记录器适配器
    /// </summary>
    /// <remarks>提供了日志记录器与日志存储器之间的适配功能</remarks>
    /// <history>
    /// [zanezeng]               2010/1/22 16:51    创建
    /// </history>
    internal class AppenderAdapter : ILogAppender
    {
        #region ---Constructor

        /// <summary>
        /// 初始化类型<see cref="AppenderAdapter"/>的新实例
        /// </summary>
        /// <param name="appenderName">适配的日志记录器的名称</param>
        /// <param name="repository">适配的日志存储器对象</param>
        /// <param name="appender">适配的日志记录器</param>
        /// <remarks></remarks>
        /// <exception cref="ArgumentNullException"><paramref name="appenderName"/>为<c>null</c>引用。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="repository"/>为<c>null</c>引用。</exception>
        /// <history>
        /// [zanezeng]               2010/1/22 16:53    创建
        /// </history>
        public AppenderAdapter(string appenderName, ILogAppender appender, ILoggingRepository repository)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(appenderName, "appenderName");
            ArgumentAssert.AssertArgumentNotNull(repository, "repository");

            //记录参数
            this.m_AppenderName = appenderName;
            this.m_Repository = repository;
            this.m_Appender = appender;

            //挂接事件
            repository.ConfigurationChanged += OnRepositoryChanged;
            repository.ConfigurationReset += OnRepositoryChanged;
        }

        /// <summary>
        /// 初始化类型<see cref="AppenderAdapter"/>的新实例
        /// </summary>
        /// <param name="appenderName">适配的日志记录器的名称</param>
        /// <param name="repository">适配的日志存储器对象</param>
        /// <remarks></remarks>
        /// <exception cref="ArgumentNullException"><paramref name="appenderName"/>为<c>null</c>引用。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="repository"/>为<c>null</c>引用。</exception>
        /// <history>
        /// [zanezeng]               2010/1/22 16:53    创建
        /// </history>
        public AppenderAdapter(string appenderName, ILoggingRepository repository)
            : this(appenderName, null, repository)
        {
        }

        #endregion

        #region ILogAppender

        /// <summary>
        /// 获得日志追加器的名称
        /// </summary>
        /// <value>日志追加器的名称</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 12:29    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/11/24 15:01    创建
        /// </history>
        public string Name
        {
            get
            {
                return this.m_AppenderName;
            }
        }

        /// <summary>
        /// 获得或者设置设置当前日志追加器是否可用
        /// </summary>
        /// <value>
        /// 	<c>true</c>：日志追加器可用<br/>
        /// 	<c>false</c>：日志追加器不可用
        /// </value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 12:27    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/22 16:59    创建
        /// </history>
        public bool IsEnabled
        {
            get
            {
                //转调
                return (null != this.Appender) ? this.Appender.IsClosed : false;
            }
            set
            {
                //判断日志记录器是否存在
                if (null != this.Appender)
                {
                    //如果存在，则转调
                    this.Appender.IsEnabled = value;
                }
            }
        }

        /// <summary>
        /// 获得一个值，该值用于判断当前日志记录器是否已经被关闭
        /// </summary>
        /// <value>
        /// 	<c>true</c>：日志记录器已经被关闭<br/>
        /// 	<c>false</c>：日志记录器尚未被关闭
        /// </value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/10/9 16:57    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/22 17:03    创建
        /// </history>
        public bool IsClosed
        {
            get
            {
                //转调
                return (null != this.Appender) ? this.Appender.IsClosed : false;
            }
        }

        /// <summary>
        /// 向当前的日志追加器中添加一条日志记录
        /// </summary>
        /// <param name="entry">要添加到当前日志追加器中的日志记录</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/22 17:42    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/22 17:01    创建
        /// </history>
        public void Append(LogEntry entry)
        {
            //判断日志记录器是否存在
            if (null != this.Appender)
            {
                //如果存在，则转调
                this.Appender.Append(entry);
            }
        }

        /// <summary>
        /// 关闭当前日志记录器
        /// </summary>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 14:52    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/22 17:01    创建
        /// </history>
        public void Close()
        {
            //判断日志记录器是否存在
            if (null != this.Appender)
            {
                //如果存在，则转调
                this.Appender.Close();
            }
        }

        #endregion

        #region ---ILogFilterAttachable

        /// <summary>
        /// 获得关联的所有日志过滤器
        /// </summary>
        /// <value>关联的所有日志过滤器</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 12:11    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/22 16:59    创建
        /// </history>
        public ILogFilter[] Filters
        {
            get
            {
                //判断日志记录器是否存在
                if (null != this.Appender)
                {
                    //如果存在，则转调
                    return this.Appender.Filters;
                }

                //默认返回空数组
                return new ILogFilter[0];
            }
        }

        /// <summary>
        /// 添加日志过滤器
        /// </summary>
        /// <param name="filter">要添加的日志过滤器</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 12:12    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/22 17:00    创建
        /// </history>
        public void AddFilter(ILogFilter filter)
        {
            //判断日志记录器是否存在
            if (null != this.Appender)
            {
                //如果存在，则转调
                this.Appender.AddFilter(filter);
            }
        }

        /// <summary>
        /// 删除指定日志过滤器
        /// </summary>
        /// <param name="filter">要删除的日志过滤器</param>
        /// <returns>
        /// 	<c>true</c>：删除成功<br/>
        /// 	<c>false</c>：删除失败
        /// </returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 12:14    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/22 17:01    创建
        /// </history>
        public bool RemoveFilter(ILogFilter filter)
        {
            //判断日志记录器是否存在
            if (null != this.Appender)
            {
                //如果存在，则转调
                return this.Appender.RemoveFilter(filter);
            }

            //默认返回失败
            return false;
        }

        /// <summary>
        /// 清除所有的日志过滤器
        /// </summary>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 12:17    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/22 17:01    创建
        /// </history>
        public void ClearFilters()
        {
            //判断日志记录器是否存在
            if (null != this.Appender)
            {
                //如果存在，则转调
                this.Appender.ClearFilters();
            }
        }

        #endregion

        #region ---IDisposable

        /// <summary>
        /// 执行与释放或重置非托管资源相关的应用程序定义的任务
        /// </summary>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/22 17:01    创建
        /// </history>
        public void Dispose()
        {

        }

        #endregion

        #region ---Property

        /// <summary>
        /// 获得适配的日志记录器
        /// </summary>
        /// <value>适配的日志记录器</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/22 17:02    创建
        /// </history>
        private ILogAppender Appender
        {
            get
            {
                //判断是否设置了适配的日志记录器
                if (null != this.m_Appender)
                {
                    //返回适配的日志记录器
                    return this.m_Appender;
                }

                //判断日志存储器是否已经被处置
                if (this.m_Repository.IsClosed)
                {
                    //如果日志存储器已经被处置，则直接返回空的日志记录器
                    return null;
                }

                //获得日志记录器
                this.m_Appender = this.m_Repository.GetAppender(this.m_AppenderName);

                //返回日志记录器
                return this.m_Appender;
            }
        }

        #endregion

        #region ---Private Method

        /// <summary>
        /// 重置适配的日志记录器
        /// </summary>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/22 16:58    创建
        /// </history>
        private void ResetAppender()
        {
            //清除日志记录器
            this.m_Appender = null;
        }

        /// <summary>
        /// 用于处理日志存储器变化事件
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">包含事件数据的<see cref="System.EventArgs"/>实例</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/10/16 10:48    创建
        /// </history>
        private void OnRepositoryChanged(object sender, EventArgs e)
        {
            //重置日志记录器
            this.ResetAppender();
        }

        #endregion

        #region ---Field

        /// <summary>
        /// 适配的日志记录器的名称
        /// </summary>
        private volatile string m_AppenderName;

        /// <summary>
        /// 适配的日志存储器
        /// </summary>
        private ILoggingRepository m_Repository;

        /// <summary>
        /// 适配的日志记录器
        /// </summary>
        private volatile ILogAppender m_Appender;

        #endregion
    }
}
